home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume3 / go / part01 next >
Encoding:
Internet Message Format  |  1988-03-09  |  59.5 KB

  1. Path: uunet!husc6!bloom-beacon!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request
  2. From: games-request@tekred.TEK.COM
  3. Newsgroups: comp.sources.games
  4. Subject: v03i097:  go - go board manager sources, Part01/05
  5. Message-ID: <2268@tekred.TEK.COM>
  6. Date: 9 Mar 88 17:55:41 GMT
  7. Sender: billr@tekred.TEK.COM
  8. Lines: 2013
  9. Approved: billr@tekred.TEK.COM
  10.  
  11. Submitted by: Fred Hansen <wjh+@andrew.cmu.edu>
  12. Comp.sources.games: Volume 3, Issue 97
  13. Archive-name: go/Part01
  14.  
  15.     [Here's a good project for a go or Pascal lover. As noted
  16.      in the README file, this will take some some work to get
  17.      it running on Unix. If somewon takes up the challenge,
  18.      please send me your results so I can share them with
  19.      the rest of the net.    -br
  20.      P.S. Three of the files have ^G characters in them. If they
  21.      unpack with errors, look for the comment "control-G" and fix
  22.      the "write('');" to be "write('^G');".]
  23.  
  24. #! /bin/sh
  25. # This is a shell archive.  Remove anything before this line, then unpack
  26. # it by saving it into a file and typing "sh file".  To overwrite existing
  27. # files, type "sh file -c".  You can also feed this as standard input via
  28. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  29. # will see the following message at the end:
  30. #        "End of archive 1 (of 5)."
  31. # Contents:  README MANIFEST goCom.pas goPlayUtils.pas
  32. # Wrapped by billr@saab on Wed Mar  9 09:14:43 1988
  33. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  34. if test -f README -a "${1}" != "-c" ; then 
  35.   echo shar: Will not over-write existing file \"README\"
  36. else
  37. echo shar: Extracting \"README\" \(597 characters\)
  38. sed "s/^X//" >README <<'END_OF_README'
  39. XThis go board manager and rudimentary go player was written by
  40. XStoney Ballard at Perq Systems in 1983-1984.  It is written in
  41. XPerq Pascal and utilizes some Perq libraries for I/O.  The code
  42. Xis offered here if someone is interested to convert it to Unix.
  43. X
  44. XThe wonderful part about it is that a game is recorded as a tree
  45. Xand can be played forward or backward, branching at any point
  46. Xwhere there were alternate moves.
  47. X
  48. XFor some time, this program was also used to generate the go
  49. Xboards displayed in the American Go Journal.  For this it used
  50. Xsome large font digits which are now lost.
  51. X
  52. XFred Hansen
  53. END_OF_README
  54. if test 597 -ne `wc -c <README`; then
  55.     echo shar: \"README\" unpacked with wrong size!
  56. fi
  57. # end of overwriting check
  58. fi
  59. if test -f MANIFEST -a "${1}" != "-c" ; then 
  60.   echo shar: Will not over-write existing file \"MANIFEST\"
  61. else
  62. echo shar: Extracting \"MANIFEST\" \(414 characters\)
  63. sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
  64. X   File Name        Archive #    Description
  65. X-----------------------------------------------------------
  66. X MANIFEST                  1    This shipping list
  67. X README                    1    
  68. X go.pas                    4    
  69. X goBoard.pas               3    
  70. X goCom.pas                 1    
  71. X goMenu.pas                5    
  72. X goMgr.pas                 4    
  73. X goPlayUtils.pas           1    
  74. X goPlayer.pas              2    
  75. X goTree.pas                3    
  76. END_OF_MANIFEST
  77. if test 414 -ne `wc -c <MANIFEST`; then
  78.     echo shar: \"MANIFEST\" unpacked with wrong size!
  79. fi
  80. # end of overwriting check
  81. fi
  82. if test -f goCom.pas -a "${1}" != "-c" ; then 
  83.   echo shar: Will not over-write existing file \"goCom.pas\"
  84. else
  85. echo shar: Extracting \"goCom.pas\" \(3924 characters\)
  86. sed "s/^X//" >goCom.pas <<'END_OF_goCom.pas'
  87. X{---------------------------------------------------------------------------}
  88. X{ goCom.Pas                                                                 }
  89. X{                                                                           }
  90. X{ Common Data for Go                                                        }
  91. X{ Copyright (c) 1982 by Three Rivers Computer Corp.                         }
  92. X{                                                                           }
  93. X{ Written: June 3, 1982 by Stoney Ballard                                   }
  94. X{ Edit History:                                                             }
  95. X{    June  3, 1982 Started                                                  }
  96. X{    June  4, 1982 Add dead group removal                                   }
  97. X{    June 10, 1982 Use new go file manager                                  }
  98. X{    Nov   9, 1982 Split From Go.Pas                                        }
  99. X{ V3.5 - Jan 11, 1983 Fixed bug in printer that screwed capture count       }
  100. X{ V3.6 - Jan 14, 1983 Changed Scoring and board coordinates to conform to   }
  101. X{                     tournament rules                                      }
  102. X{ V3.7 - Jan 17, 1983 added computer player!!!!                             }
  103. X{ V3.8 - Mar  8, 1983 Added PrintDiagram                                    }
  104. X{                     Made board 34 grid for printing                       }
  105. X{ V3.9 - May  3, 1983 Add board print size switch and command               }
  106. X{---------------------------------------------------------------------------}
  107. X
  108. X
  109. Xmodule goCom;
  110. X
  111. Xexports
  112. X
  113. Ximports IO_Others from IO_Others;
  114. Ximports fileDefs from fileDefs;
  115. X
  116. Xconst
  117. X  version = '3.9';
  118. X
  119. X  numPoints = 19;
  120. X  maxPoint = numPoints - 1;
  121. X  curC = 31;
  122. X  maxTagLen = 16;
  123. X
  124. X  charHeight = 13;
  125. X  charWidth = 9;
  126. X
  127. X  boardWin = 1;
  128. X  menuWin = 2;
  129. X  statWin = 3;
  130. X  bWinX = 0;
  131. X  bWinY = 0;
  132. X  bWinW = 768;
  133. X  bWinH = 768;
  134. X  mWinX = 0;
  135. X  mWinY = 768;
  136. X  mWinW = 768;
  137. X  mWinH = 192;
  138. X  sWinX = 0;
  139. X  sWinY = 960;
  140. X  sWinW = 768;
  141. X  sWinH = 64;
  142. X
  143. X  promptX = sWinX + 32;
  144. X  lineY = 4;
  145. X  lineDel = 2;
  146. X  promptLine = 1;
  147. X  tagLine = 2;
  148. X  cmtLine = 3;
  149. X
  150. X  boardX = bWinX + 64;
  151. X  boardY = bWinY + 32;
  152. X  pBoardX = bWinX + 44;  { for printing }
  153. X  pBoardY = bWinY + 24;
  154. X  
  155. X  passX = bWinX + 321;
  156. X  passY = bWinY + 712;  { 712 }
  157. X  passW = 126;
  158. X  passH = 13;
  159. X
  160. X  captBX = bWinX + 64;
  161. X  captWX = bWinX + 578;
  162. X  captY = bWinY + 712;  { 712 }
  163. X
  164. X  captNBX = captBX + 45;
  165. X  captNWX = captWX + 45;
  166. X  captNY = bWinY + 732; { 732 }
  167. X
  168. X  turnX = bWinX + 325;
  169. X  turnY = bWinY + 752;  { 752 }
  170. X
  171. X  none = -1;
  172. X  mInit = 1;
  173. X  mSetHc = 2;
  174. X  mPass = 3;
  175. X  mScore = 4;
  176. X  mForToBr = 5;
  177. X  mBackToBr = 6;
  178. X  mBackToStone = 7;
  179. X  mForToLeaf = 8;
  180. X  mPutTag = 9;
  181. X  mGotoTag = 10;
  182. X  mGotoRoot = 11;
  183. X  mPutCmt = 12; 
  184. X  mReadFile = 13;
  185. X  mWriteFile = 14;
  186. X  mPruneBranches = 15;
  187. X  mTogNums = 16;
  188. X  mPrintBoard = 17;
  189. X  mStepToTag = 18;
  190. X  mSetStepTag = 19;
  191. X  mQuit = 20;
  192. X  mBackOne = 21;
  193. X  mForOne = 22;
  194. X  mEraseMove = 23;
  195. X  mAutoPlay = 24;
  196. X  mPlayMyself = 25;
  197. X  mSetPlayLevel = 26;
  198. X  mDebug = 27;
  199. X  mRefBoard = 28;
  200. X  mShoState = 29;
  201. X  mPrintDiag = 30;
  202. X  mBoardSize = 31;
  203. X  mLast = 31;  { the last command in the menu }
  204. X  mPlaceStone = 32;  { this command is not in the menu }
  205. X  mCtlC = 33;   { nor is this }
  206. X
  207. Xtype
  208. X  bVal = (black, white, empty, alternate); 
  209. X  sType = black..white;
  210. X  bRec = record
  211. X           val: bval;
  212. X           xOfs, yOfs: integer;
  213. X           mNum: integer;
  214. X           marked: boolean;
  215. X         end;
  216. X
  217. X  boardArray = array[0..maxPoint] of array[0..maxPoint] of bRec;
  218. X
  219. X  picBuf = array[0..63] of array[0..3] of integer;
  220. X  pPicBuf = ^picBuf;
  221. X
  222. Xvar
  223. X  board: boardArray;
  224. X  captures: array[sType] of integer;
  225. X  moveNum: integer;
  226. X  koX, koY: integer;
  227. X  selCursor: curPatPtr;
  228. X  dotSX, dotSY: integer;
  229. X  passShowing: boolean;
  230. X  numbEnabled: boolean;
  231. X  treeDirty: boolean;
  232. X  gameFName: pathName;
  233. X  debug: boolean;
  234. X  printLarge: boolean;
  235. X
  236. Xprivate
  237. X
  238. Xprocedure comBug;
  239. Xbegin { comBug }
  240. Xend. { comBug }
  241. END_OF_goCom.pas
  242. if test 3924 -ne `wc -c <goCom.pas`; then
  243.     echo shar: \"goCom.pas\" unpacked with wrong size!
  244. fi
  245. # end of overwriting check
  246. fi
  247. if test -f goPlayUtils.pas -a "${1}" != "-c" ; then 
  248.   echo shar: Will not over-write existing file \"goPlayUtils.pas\"
  249. else
  250. echo shar: Extracting \"goPlayUtils.pas\" \(50784 characters\)
  251. sed "s/^X//" >goPlayUtils.pas <<'END_OF_goPlayUtils.pas'
  252. Xmodule goPlayUtils;
  253. X
  254. Xexports
  255. X
  256. Ximports goCom from goCom;
  257. X
  258. Xconst
  259. X  iNil = 32767; { a distinguished value like nil }
  260. X  maxGroup = 512;
  261. X  maxSPoint = 16;
  262. X
  263. Xtype
  264. X  intBoard = array[-2..maxPoint + 2] of array[-2..maxPoint + 2] of integer;
  265. X
  266. X  boolBoard = array[-2..maxPoint + 2] of array[-2..maxPoint + 2] of boolean;
  267. X
  268. X  point = record
  269. X            px, py: integer;
  270. X          end;
  271. X
  272. X  pointList = record
  273. X                p: array[1..400] of point;
  274. X                indx: integer;
  275. X              end;
  276. X
  277. X  sPointList = record
  278. X                 p: array[1..maxSPoint] of point;
  279. X                 indx: integer;
  280. X               end;
  281. X
  282. X  intList = record
  283. X              indx: integer;
  284. X              v: array[1..400] of integer;
  285. X            end;
  286. X
  287. X  sgRec = record
  288. X            w, s, sm: integer;
  289. X          end;
  290. X
  291. X  groupRec = record
  292. X               groupMark: integer;
  293. X               atLevel: integer;
  294. X               isLive: boolean;
  295. X               isDead: boolean;
  296. X               libC: integer;
  297. X               numEyes: integer;
  298. X               size: integer;
  299. X               lx, ly: integer;
  300. X             end;
  301. X
  302. Xvar
  303. X  kleim, ekstre, bord, ndbord, sGroups, threatBord: intBoard;
  304. X  groupIDs, connectMap, protPoints: intBoard;
  305. X  groupSeen, legal: boolBoard;
  306. X  maxGroupID: integer;
  307. X  pList, pList1, plist2, plist3, pPlist: pointList;
  308. X  nlcGroup, aList: intList;
  309. X  sList: array[1..400] of sgRec;
  310. X  gList: array[0..maxGroup] of groupRec;
  311. X  killFlag: boolean;
  312. X  numCapt: integer;
  313. X  utilPlayLevel: integer;
  314. X  treeLibLim: integer;
  315. X  mySType: sType;
  316. X  showTrees: boolean;
  317. X  sGlist: array[1..maxGroup] of integer;
  318. X  depthLimit: integer;
  319. X  markBoard: intBoard;
  320. X  marker: integer;
  321. X
  322. Xfunction saveable(gx, gy: integer; var savex, savey: integer): boolean;
  323. Xfunction killable(gx, gy: integer; var killx, killy: integer): boolean;
  324. Xprocedure initBoolBoard(var bb: boolBoard);
  325. Xprocedure spanGroup(x, y: integer; var libs: pointList);
  326. Xfunction abs(i: integer): integer;
  327. Xprocedure intersectPlist(var p1, p2, pr: pointList);
  328. Xprocedure initArray(var ary: intBoard);
  329. Xprocedure initState;
  330. Xprocedure copyArray(var dAry, sAry: intBoard);
  331. Xprocedure steik;
  332. Xprocedure spread;
  333. Xprocedure respreicen;
  334. Xprocedure plei(x, y, z: integer);
  335. Xprocedure genState;
  336. Xprocedure saveState;
  337. Xprocedure restoreState;
  338. Xfunction tencen(x, y: integer): integer;
  339. Xprocedure genConnects;
  340. Xprocedure initGPUtils;
  341. Xprocedure sortLibs;
  342. X
  343. Xprivate
  344. X
  345. Ximports screen from screen;
  346. Ximports raster from raster;
  347. Ximports goBoard from goBoard;
  348. Ximports io_others from io_others;
  349. X
  350. Xtype
  351. X  playType = (rem, add, chLib, reMap);
  352. X
  353. X  playRec = record
  354. X              gID: integer;
  355. X              case kind: playType of
  356. X                rem, add:
  357. X                  (who, xl, yl, nextGID, sNumber: integer);
  358. X                chLib:
  359. X                  (oldLC, oldLevel: integer);
  360. X                reMap:
  361. X                  (oldGID: integer)
  362. X            end;
  363. X
  364. Xvar
  365. X  adjInAtari, adj2Libs: boolean;
  366. X  intersectNum, spanNum, libMark: integer;
  367. X  playStack: array[1..1024] of playRec;
  368. X  playMark: integer;
  369. X  newGID: integer;
  370. X  tryLevel: integer;
  371. X  grpMark: integer;
  372. X  gMap: array[0..maxGroup] of integer;
  373. X  dbStop, inGenState: boolean;
  374. X
  375. Xexception screwup;
  376. X
  377. Xprocedure pause;
  378. Xbegin { pause }
  379. X{  if dbStop and not inGenState then
  380. X    begin
  381. X      while not tabswitch do;
  382. X      repeat
  383. X        if tabYellow then
  384. X          dbStop := false;
  385. X      until not tabswitch;
  386. X    end;     }
  387. Xend { pause };
  388. X
  389. Xprocedure sstone(w, x, y, numb: integer);
  390. Xvar
  391. X  cx, cy: integer;
  392. Xbegin { sstone }
  393. X  sReadCursor(cx, cy);
  394. X  if w = 1 then
  395. X    placeStone(mySType, x, y, 0, 0, numb)
  396. X  else if mySType = white then
  397. X    placeStone(black, x, y, 0, 0, numb)
  398. X  else
  399. X    placeStone(white, x, y, 0, 0, numb);
  400. X  sSetCursor(cx, cy);
  401. Xend { sstone };
  402. X
  403. Xprocedure rstone(x, y: integer);
  404. Xvar
  405. X  cx, cy: integer;
  406. Xbegin { rstone }
  407. X  sReadCursor(cx, cy);
  408. X  remStone(x, y);
  409. X  sSetCursor(cx, cy);
  410. Xend { rstone };
  411. X
  412. Xprocedure initBoolBoard(var bb: boolBoard);
  413. Xvar
  414. X  i, j: integer;
  415. Xbegin { initBoolBoard }
  416. X  for i := 0 to maxPoint do
  417. X    for j := 0 to maxPoint do
  418. X      bb[i, j] := false;
  419. Xend { initBoolBoard };
  420. X
  421. Xfunction abs(i: integer): integer;
  422. Xbegin { abs }
  423. X  if i < 0 then
  424. X    abs := -i
  425. X  else
  426. X    abs := i;  
  427. Xend { abs };
  428. X
  429. Xprocedure sortLibs;
  430. Xvar
  431. X  i, j, t: integer;
  432. Xbegin { sortLibs }
  433. X  for i := 1 to maxGroupID do
  434. X    sGList[i] := i;
  435. X  for i := 1 to maxGroupID - 1 do
  436. X    for j := i + 1 to maxGroupID do
  437. X      if gList[sGlist[i]].libC > gList[sGlist[j]].libC then
  438. X        begin
  439. X          t := sGList[i];
  440. X          sGlist[i] := sGlist[j];
  441. X          sGlist[j] := t;
  442. X        end;
  443. Xend { sortLibs };
  444. X
  445. Xprocedure spanGroup(x, y: integer; var libs: pointList);
  446. Xvar
  447. X  lookFor: integer;
  448. X
  449. X  procedure span(x, y: integer);
  450. X  begin { span }
  451. X    markBoard[x, y] := marker;
  452. X    if bord[x, y] = 0 then
  453. X      begin
  454. X        libs.indx := libs.indx + 1;
  455. X        libs.p[libs.indx].px := x;
  456. X        libs.p[libs.indx].py := y;
  457. X      end
  458. X    else if bord[x, y] = lookFor then
  459. X      begin
  460. X        groupSeen[x, y] := true;
  461. X        if (x > 0) and (markBoard[x - 1, y] <> marker) then
  462. X          span(x - 1, y);
  463. X        if (y > 0) and (markBoard[x, y - 1] <> marker) then
  464. X          span(x, y - 1);
  465. X        if (x < maxPoint) and (markBoard[x + 1, y] <> marker) then
  466. X          span(x + 1, y);
  467. X        if (y < maxPoint) and (markBoard[x, y + 1] <> marker) then
  468. X          span(x, y + 1);
  469. X      end
  470. X    else if gList[gMap[groupIDs[x, y]]].libC = 1 then 
  471. X      adjInAtari := true 
  472. X    else if (gList[gMap[groupIDs[x, y]]].libC = 2) and
  473. X            (not gList[gMap[groupIDs[x, y]]].isLive) then 
  474. X      adj2Libs := true; 
  475. X  end { span };
  476. X
  477. Xbegin { spanGroup }
  478. X  marker := marker + 1;
  479. X  if marker = 0 then
  480. X    begin
  481. X      initArray(markBoard);
  482. X      marker := 1;
  483. X    end;
  484. X  adjInAtari := false;
  485. X  adj2Libs := false;
  486. X  lookFor := bord[x, y];
  487. X  libs.indx := 0;
  488. X  span(x, y);
  489. Xend { spanGroup };
  490. X
  491. Xprocedure sSpanGroup(x, y: integer; var libs: sPointList);
  492. Xvar
  493. X  lookFor: integer;
  494. X
  495. X  procedure span(x, y: integer);
  496. X  begin { span }
  497. X    markBoard[x, y] := marker;
  498. X    if bord[x, y] = 0 then
  499. X      begin
  500. X        libs.indx := libs.indx + 1;
  501. X        if libs.indx <= maxSPoint then
  502. X          begin
  503. X            libs.p[libs.indx].px := x;
  504. X            libs.p[libs.indx].py := y;
  505. X          end;
  506. X      end
  507. X    else if bord[x, y] = lookFor then
  508. X      begin
  509. X        groupSeen[x, y] := true;
  510. X        if (x > 0) and (markBoard[x - 1, y] <> marker) then
  511. X          span(x - 1, y);
  512. X        if (y > 0) and (markBoard[x, y - 1] <> marker) then
  513. X          span(x, y - 1);
  514. X        if (x < maxPoint) and (markBoard[x + 1, y] <> marker) then
  515. X          span(x + 1, y);
  516. X        if (y < maxPoint) and (markBoard[x, y + 1] <> marker) then
  517. X          span(x, y + 1);
  518. X      end
  519. X    else if gList[gMap[groupIDs[x, y]]].libC = 1 then 
  520. X      adjInAtari := true 
  521. X    else if (gList[gMap[groupIDs[x, y]]].libC = 2) and
  522. X            (not gList[gMap[groupIDs[x, y]]].isLive) then 
  523. X      adj2Libs := true; 
  524. X  end { span };
  525. X
  526. Xbegin { sSpanGroup }
  527. X  marker := marker + 1;
  528. X  if marker = 0 then
  529. X    begin
  530. X      initArray(markBoard);
  531. X      marker := 1;
  532. X    end;
  533. X  adjInAtari := false;
  534. X  adj2Libs := false;
  535. X  lookFor := bord[x, y];
  536. X  libs.indx := 0;
  537. X  span(x, y);
  538. Xend { sSpanGroup };
  539. X
  540. Xprocedure listAdjacents(x, y: integer; var iL: intList);
  541. Xvar
  542. X  me, him: integer;
  543. X
  544. X  procedure span(x, y: integer);
  545. X  begin { span }
  546. X    markBoard[x, y] := marker;
  547. X    if bord[x, y] = me then
  548. X      begin
  549. X        if (x > 0) and (markBoard[x - 1, y] <> marker) then
  550. X          span(x - 1, y);
  551. X        if (x < maxPoint) and (markBoard[x + 1, y] <> marker) then
  552. X          span(x + 1, y);
  553. X        if (y > 0) and (markBoard[x, y - 1] <> marker) then
  554. X          span(x, y - 1);
  555. X        if (y < maxPoint) and (markBoard[x, y + 1] <> marker) then
  556. X          span(x, y + 1);
  557. X      end
  558. X    else if bord[x, y] = him then
  559. X      if gList[gMap[groupIDs[x, y]]].groupMark <> grpMark then
  560. X        begin
  561. X          gList[gMap[groupIDs[x, y]]].groupMark := grpMark;
  562. X          iL.indx := iL.indx + 1;
  563. X          iL.v[iL.indx] := gMap[groupIDs[x, y]];
  564. X        end;
  565. X  end { span };
  566. X
  567. Xbegin { listAdjacents }
  568. X  grpMark := grpMark + 1;
  569. X  marker := marker + 1;
  570. X  if marker = 0 then
  571. X    begin
  572. X      initArray(markBoard);
  573. X      marker := 1;
  574. X    end;
  575. X  iL.indx := 0;
  576. X  me := bord[x, y];
  577. X  him := -me;
  578. X  span(x, y);
  579. Xend { listAdjacents };
  580. X
  581. Xprocedure listDiags(x, y: integer; var diags: sPointList);
  582. Xvar
  583. X  me: integer;
  584. X
  585. X  procedure span(x, y: integer);
  586. X  begin { span }
  587. X    markBoard[x, y] := marker;
  588. X    if (x > 0) and (y > 0) and
  589. X       (bord[x - 1, y - 1] = 0) and
  590. X       (bord[x, y - 1] <> me) and
  591. X       (bord[x - 1, y] <> me) and
  592. X       (markBoard[x - 1, y - 1] <> marker) then
  593. X      begin
  594. X        markBoard[x - 1, y - 1] := marker;
  595. X        diags.indx := diags.indx + 1;
  596. X        if diags.indx <= maxSPoint then
  597. X          with diags.p[diags.indx] do
  598. X            begin
  599. X              px := x - 1;
  600. X              py := y - 1;
  601. X            end;
  602. X      end;
  603. X    if (x < maxPoint) and (y > 0) and
  604. X       (bord[x + 1, y - 1] = 0) and
  605. X       (bord[x, y - 1] <> me) and
  606. X       (bord[x + 1, y] <> me) and
  607. X       (markBoard[x + 1, y - 1] <> marker) then
  608. X      begin
  609. X        markBoard[x + 1, y - 1] := marker;
  610. X        diags.indx := diags.indx + 1;
  611. X        if diags.indx <= maxSPoint then
  612. X          with diags.p[diags.indx] do
  613. X            begin
  614. X              px := x + 1;
  615. X              py := y - 1;
  616. X            end;
  617. X      end;
  618. X    if (x > 0) and (y < maxPoint) and
  619. X       (bord[x - 1, y + 1] = 0) and
  620. X       (bord[x, y + 1] <> me) and
  621. X       (bord[x - 1, y] <> me) and
  622. X       (markBoard[x - 1, y + 1] <> marker) then
  623. X      begin
  624. X        markBoard[x - 1, y + 1] := marker;
  625. X        diags.indx := diags.indx + 1;
  626. X        if diags.indx <= maxSPoint then
  627. X          with diags.p[diags.indx] do
  628. X            begin
  629. X              px := x - 1;
  630. X              py := y + 1;
  631. X            end;
  632. X      end;
  633. X    if (x < maxPoint) and (y < maxPoint) and
  634. X       (bord[x + 1, y + 1] = 0) and
  635. X       (bord[x, y + 1] <> me) and
  636. X       (bord[x + 1, y] <> me) and
  637. X       (markBoard[x + 1, y + 1] <> marker) then
  638. X      begin
  639. X        markBoard[x + 1, y + 1] := marker;
  640. X        diags.indx := diags.indx + 1;
  641. X        if diags.indx <= maxSPoint then
  642. X          with diags.p[diags.indx] do
  643. X            begin
  644. X              px := x + 1;
  645. X              py := y + 1;
  646. X            end;
  647. X      end;
  648. X    if (x > 0) and (bord[x - 1, y] = me) and
  649. X       (markBoard[x - 1, y] <> marker) then
  650. X      span(x - 1, y);
  651. X    if (x < maxPoint) and (bord[x + 1, y] = me) and
  652. X       (markBoard[x + 1, y] <> marker) then
  653. X      span(x + 1, y);
  654. X    if (y > 0) and (bord[x, y - 1] = me) and
  655. X       (markBoard[x, y - 1] <> marker) then
  656. X      span(x, y - 1);
  657. X    if (y < maxPoint) and (bord[x, y + 1] = me) and
  658. X       (markBoard[x, y + 1] <> marker) then
  659. X      span(x, y + 1);
  660. X  end { span };
  661. X
  662. Xbegin { listDiags }
  663. X  me := bord[x, y];
  664. X  diags.indx := 0;
  665. X  marker := marker + 1;
  666. X  if marker = 0 then
  667. X    begin
  668. X      initArray(markBoard);
  669. X      marker := 1;
  670. X    end;
  671. X  span(x, y);
  672. Xend { listDiags };
  673. X
  674. Xprocedure intersectPlist(var p1, p2, pr: pointList);
  675. Xvar
  676. X  i, j, k: integer;
  677. Xbegin { intersectPlist }
  678. X  marker := marker + 1;
  679. X  if marker = 0 then
  680. X    begin
  681. X      initArray(markBoard);
  682. X      marker := 1;
  683. X    end;
  684. X  pr.indx := 0;
  685. X  for i := 1 to p1.indx do
  686. X    with p1.p[i] do
  687. X      markBoard[px, py] := marker;
  688. X  j := 0;
  689. X  for i := 1 to p2.indx do
  690. X    with p2.p[i] do
  691. X      if markBoard[px, py] = marker then
  692. X        begin
  693. X          j := j + 1;
  694. X          pr.p[j] := p2.p[i];
  695. X        end;
  696. X  pr.indx := j;
  697. Xend { intersectPlist };
  698. X
  699. Xprocedure initArray(var ary: intBoard);
  700. Xvar
  701. X  i, j: integer;
  702. Xbegin { initArray }
  703. X  for i := 0 to maxPoint do
  704. X    for j := 0 to maxPoint do
  705. X      ary[i, j] := 0;
  706. Xend { initArray };
  707. X
  708. Xprocedure initState;
  709. Xvar
  710. X  i, j: integer;
  711. Xbegin { initState }
  712. X  for i := -2 to maxPoint + 2 do
  713. X    for j := -2 to maxPoint + 2 do
  714. X      begin
  715. X        ekstre[i, j] := 0;
  716. X        kleim[i, j] := 0;
  717. X        groupIDs[i, j] := 0;
  718. X        connectMap[i, j] := 0;
  719. X        protPoints[i, j] := 0;
  720. X      end;
  721. Xend { initState };
  722. X
  723. Xprocedure copyArray(var dAry, sAry: intBoard);
  724. Xvar
  725. X  i, j: integer;
  726. Xbegin { copyArray }
  727. X  for i := 0 to maxPoint do
  728. X    for j := 0 to maxPoint do
  729. X      dAry[i, j] := sAry[i, j];
  730. Xend { copyArray };
  731. X
  732. X{
  733. X  generates a one-point spread in the force field array (kleim)
  734. X
  735. X  the spread from a single point after four calls is:
  736. X
  737. X              1
  738. X           2  2  2
  739. X        2  4  6  4  2
  740. X     2  4  8 10  8  4  2
  741. X  1  2  6 10 62 10  6  2  1  
  742. X     2  4  8 10  8  4  2
  743. X        2  4  6  4  2
  744. X           2  2  2
  745. X              1
  746. X
  747. X}
  748. Xprocedure steik;
  749. Xvar
  750. X  i, j: integer;
  751. Xbegin { steik }
  752. X  initArray(ekstre);
  753. X  for i := 0 to maxPoint do
  754. X    for j := 0 to maxPoint do
  755. X      begin
  756. X        ekstre[i, j] := ekstre[i, j] + kleim[i, j];
  757. X        if kleim[i, j] > 0 then
  758. X          begin
  759. X            if i > 0 then
  760. X              ekstre[i - 1, j] := ekstre[i - 1, j] + 1;
  761. X            if j > 0 then
  762. X              ekstre[i, j - 1] := ekstre[i, j - 1] + 1;
  763. X            if i < maxPoint then
  764. X              ekstre[i + 1, j] := ekstre[i + 1, j] + 1;
  765. X            if j < maxPoint then
  766. X              ekstre[i, j + 1] := ekstre[i, j + 1] + 1;
  767. X          end
  768. X        else if kleim[i, j] < 0 then
  769. X          begin
  770. X            if i > 0 then
  771. X              ekstre[i - 1, j] := ekstre[i - 1, j] - 1;
  772. X            if j > 0 then
  773. X              ekstre[i, j - 1] := ekstre[i, j - 1] - 1;
  774. X            if i < maxPoint then
  775. X              ekstre[i + 1, j] := ekstre[i + 1, j] - 1;
  776. X            if j < maxPoint then
  777. X              ekstre[i, j + 1] := ekstre[i, j + 1] - 1;
  778. X          end;
  779. X      end;
  780. X  copyArray(kleim, ekstre);
  781. Xend { steik };
  782. X
  783. X{
  784. X  sets up kleim from the current board position
  785. X}
  786. Xprocedure spread;
  787. Xvar
  788. X  i, j: integer;
  789. Xbegin { spread }
  790. X  for i := 0 to maxPoint do
  791. X    for j := 0 to maxPoint do
  792. X      kleim[i, j] := ndbord[i, j] * 50;
  793. X  steik;
  794. X  steik;
  795. X  steik;
  796. X  steik;
  797. Xend { spread };
  798. X
  799. X{
  800. X  gList is initialized with the size, loc, and libCount of each group
  801. X  groupIDs contains the serial numbers of the groups.
  802. X}
  803. Xprocedure respreicen;
  804. Xvar
  805. X  i, j, gID, libCount, gSize, who: integer;
  806. X
  807. X  procedure span(x, y: integer);
  808. X  begin { span }
  809. X    if (bord[x, y] = 0) and
  810. X       (markBoard[x, y] <> marker) then { a liberty }
  811. X      begin
  812. X        markBoard[x, y] := marker;
  813. X        libCount := libCount + 1;
  814. X      end 
  815. X    else if (bord[x, y] = who) and
  816. X            (groupIDs[x, y] = 0) then
  817. X      begin
  818. X        groupIDs[x, y] := gID;
  819. X        gSize := gSize + 1;
  820. X        if x > 0 then
  821. X          span(x - 1, y);
  822. X        if x < maxPoint then
  823. X          span(x + 1, y);
  824. X        if y > 0 then
  825. X          span(x, y - 1);
  826. X        if y < maxPoint then
  827. X          span(x, y + 1);
  828. X      end;
  829. X  end { span };
  830. X
  831. Xbegin { respreicen }
  832. X  gID := 0;
  833. X  for i := 0 to maxPoint do
  834. X    for j := 0 to maxPoint do
  835. X      groupIDs[i, j] := 0;
  836. X  for i := 0 to maxPoint do
  837. X    for j := 0 to maxPoint do
  838. X      if (bord[i, j] <> 0) and   { a stone there }
  839. X         (groupIDs[i, j] = 0) then { not seen yet }
  840. X        begin
  841. X          marker := marker + 1;
  842. X          if marker = 0 then
  843. X            begin
  844. X              initArray(markBoard);
  845. X              marker := 1;
  846. X            end;
  847. X          gID := gID + 1;
  848. X          libCount := 0;
  849. X          gSize := 0;
  850. X          who := bord[i, j];
  851. X          span(i, j); { span the group, collecting info }
  852. X          with gList[gID] do
  853. X            begin
  854. X              groupMark := 0;
  855. X              atLevel := 0;
  856. X              isLive := false; { we don't know yet }
  857. X              isDead := false;
  858. X              numEyes := -1;
  859. X              size := gSize;
  860. X              libC := libCount;
  861. X              lx := i;
  862. X              ly := j;
  863. X            end;
  864. X          gMap[gID] := gID; { set up identity map }
  865. X        end;
  866. X  maxGroupID := gID;
  867. X  newGID := gID;
  868. X  grpMark := 0;
  869. Xend { respreicen };
  870. X
  871. X{
  872. X  play z at [x, y].
  873. X  killFlag is set true if anything is killed.
  874. X}
  875. Xprocedure plei(x, y, z: integer);
  876. Xvar
  877. X  i, me, him, myGID: integer;
  878. X  isNew: boolean;
  879. X
  880. X  procedure killGroup(x, y: integer);
  881. X  begin { killGroup }
  882. X    playMark := playMark + 1;
  883. X    with playStack[playMark] do
  884. X      begin                        { record this kill }
  885. X        kind := rem;
  886. X        who := him;
  887. X        xl := x;
  888. X        yl := y;
  889. X        gID := groupIDs[x, y];
  890. X        sNumber := board[x, y].mNum;
  891. X        if showTrees then
  892. X          rstone(x, y);
  893. X      end;
  894. X    numCapt := numCapt + 1;
  895. X    bord[x, y] := 0;
  896. X    groupIDs[x, y] := 0;
  897. X    if x > 0 then
  898. X      begin
  899. X        if bord[x - 1, y] = me then
  900. X          begin
  901. X            nlcGroup.indx := nlcGroup.indx + 1;
  902. X            nlcGroup.v[nlcGroup.indx] := gMap[groupIDs[x - 1, y]];
  903. X          end
  904. X        else if bord[x - 1, y] = him then
  905. X          killGroup(x - 1, y);
  906. X      end;
  907. X    if x < maxPoint then
  908. X      begin
  909. X        if bord[x + 1, y] = me then
  910. X          begin
  911. X            nlcGroup.indx := nlcGroup.indx + 1;
  912. X            nlcGroup.v[nlcGroup.indx] := gMap[groupIDs[x + 1, y]];
  913. X          end
  914. X        else if bord[x + 1, y] = him then
  915. X          killGroup(x + 1, y);
  916. X      end;
  917. X    if y > 0 then
  918. X      begin
  919. X        if bord[x, y - 1] = me then
  920. X          begin
  921. X            nlcGroup.indx := nlcGroup.indx + 1;
  922. X            nlcGroup.v[nlcGroup.indx] := gMap[groupIDs[x, y - 1]];
  923. X          end
  924. X        else if bord[x, y - 1] = him then
  925. X          killGroup(x, y - 1);
  926. X      end;
  927. X    if y < maxPoint then
  928. X      begin
  929. X        if bord[x, y + 1] = me then
  930. X          begin
  931. X            nlcGroup.indx := nlcGroup.indx + 1;
  932. X            nlcGroup.v[nlcGroup.indx] := gMap[groupIDs[x, y + 1]];
  933. X          end
  934. X        else if bord[x, y + 1] = him then
  935. X          killGroup(x, y + 1);
  936. X      end;
  937. X  end { killGroup };
  938. X
  939. X  procedure mergeGroup(sGID: integer);
  940. X  var
  941. X    i: integer;
  942. X  begin { mergeGroup }
  943. X    for i := 1 to newGID do
  944. X      if gMap[i] = sGID then
  945. X        begin
  946. X          playMark := playMark + 1;
  947. X          with playStack[playMark] do
  948. X            begin
  949. X              kind := reMap;
  950. X              gID := i;
  951. X              oldGID := sGID;
  952. X            end;
  953. X          gMap[i] := myGID;
  954. X        end;
  955. X  end { mergeGroup };
  956. X
  957. Xbegin { plei }
  958. X  me := z;
  959. X  him := -me;
  960. X  killFlag := false;  { set true if something is killed }
  961. X  numCapt := 0;
  962. X  tryLevel := tryLevel + 1;
  963. X  isNew := false;
  964. X  bord[x, y] := z;  { play the stone }
  965. X  if (x > 0) and (bord[x - 1, y] = me) then   { connect to adjacent group }
  966. X    myGID := gMap[groupIDs[x - 1, y]]
  967. X  else if (x < maxPoint) and (bord[x + 1, y] = me) then
  968. X    myGID := gMap[groupIDs[x + 1, y]]
  969. X  else if (y > 0) and (bord[x, y - 1] = me) then
  970. X    myGID := gMap[groupIDs[x, y - 1]]
  971. X  else if (y < maxPoint) and (bord[x, y + 1] = me) then
  972. X    myGID := gMap[groupIDs[x, y + 1]]
  973. X  else  { nobody to connect to }
  974. X    begin
  975. X      newGID := newGID + 1;
  976. X      isNew := true;
  977. X      myGID := newGID;
  978. X      with gList[myGID] do
  979. X        begin
  980. X          groupMark := 0;
  981. X          atLevel := tryLevel;
  982. X          isLive := false;
  983. X          numEyes := -1;
  984. X          size := -1;
  985. X          lx := x;
  986. X          ly := y;
  987. X        end;
  988. X      gMap[myGID] := myGID;
  989. X    end;
  990. X  groupIDs[x, y] := myGID;
  991. X  playMark := playMark + 1;
  992. X  with playStack[playMark] do
  993. X    begin                        { record this move }
  994. X      kind := add;
  995. X      who := me;
  996. X      xl := x;
  997. X      yl := y;
  998. X      gID := myGID;
  999. X      sNumber := 0;
  1000. X      if isNew then
  1001. X        nextGID := newGID - 1
  1002. X      else
  1003. X        nextGID := newGID;
  1004. X      if showTrees then
  1005. X        sstone(me, x, y, 0);
  1006. X    end;
  1007. X  { merge adjacent groups }
  1008. X  if (x > 0) and (bord[x - 1, y] = me) and
  1009. X     (gMap[groupIDs[x - 1, y]] <> myGID) then
  1010. X    mergeGroup(gMap[groupIDs[x - 1, y]]);
  1011. X  if (x < maxPoint) and (bord[x + 1, y] = me) and
  1012. X     (gMap[groupIDs[x + 1, y]] <> myGID) then
  1013. X    mergeGroup(gMap[groupIDs[x + 1, y]]);
  1014. X  if (y > 0) and (bord[x, y - 1] = me) and
  1015. X     (gMap[groupIDs[x, y - 1]] <> myGID) then
  1016. X    mergeGroup(gMap[groupIDs[x, y - 1]]);
  1017. X  if (y < maxPoint) and (bord[x, y + 1] = me) and
  1018. X     (gMap[groupIDs[x, y + 1]] <> myGID) then
  1019. X    mergeGroup(gMap[groupIDs[x, y + 1]]);
  1020. X  { kill opposing groups, listing affected groups }
  1021. X  nlcGroup.indx := 1;
  1022. X  nlcGroup.v[1] := myGID; { init list to include me }
  1023. X  if (x > 0) and (bord[x - 1, y] = him) and
  1024. X     (gList[gMap[groupIDs[x - 1, y]]].libC = 1) then
  1025. X    begin
  1026. X      killFlag := true;
  1027. X      killGroup(x - 1, y);
  1028. X    end;
  1029. X  if (x < maxPoint) and (bord[x + 1, y] = him) and
  1030. X     (gList[gMap[groupIDs[x + 1, y]]].libC = 1) then
  1031. X    begin
  1032. X      killFlag := true;
  1033. X      killGroup(x + 1, y);
  1034. X    end;
  1035. X  if (y > 0) and (bord[x, y - 1] = him) and
  1036. X     (gList[gMap[groupIDs[x, y - 1]]].libC = 1) then
  1037. X    begin
  1038. X      killFlag := true;
  1039. X      killGroup(x, y - 1);
  1040. X    end;
  1041. X  if (y < maxPoint) and (bord[x, y + 1] = him) and
  1042. X     (gList[gMap[groupIDs[x, y + 1]]].libC = 1) then
  1043. X    begin
  1044. X      killFlag := true;
  1045. X      killGroup(x, y + 1);
  1046. X    end;
  1047. X  { list groups adjacent to me }
  1048. X  if (x > 0) and (bord[x - 1, y] = him) then
  1049. X    begin
  1050. X      nlcGroup.indx := nlcGroup.indx + 1;
  1051. X      nlcGroup.v[nlcGroup.indx] := gMap[groupIDs[x - 1, y]];
  1052. X    end;
  1053. X  if (x < maxPoint) and (bord[x + 1, y] = him) then
  1054. X    begin
  1055. X      nlcGroup.indx := nlcGroup.indx + 1;
  1056. X      nlcGroup.v[nlcGroup.indx] := gMap[groupIDs[x + 1, y]];
  1057. X    end;
  1058. X  if (y > 0) and (bord[x, y - 1] = him) then
  1059. X    begin
  1060. X      nlcGroup.indx := nlcGroup.indx + 1;
  1061. X      nlcGroup.v[nlcGroup.indx] := gMap[groupIDs[x, y - 1]];
  1062. X    end;
  1063. X  if (y < maxPoint) and (bord[x, y + 1] = him) then
  1064. X    begin
  1065. X      nlcGroup.indx := nlcGroup.indx + 1;
  1066. X      nlcGroup.v[nlcGroup.indx] := gMap[groupIDs[x, y + 1]];
  1067. X    end;
  1068. X  { fix liberty count for affected groups }
  1069. X  grpMark := grpMark + 1;
  1070. X  for i := 1 to nlcGroup.indx do
  1071. X    with gList[nlcGroup.v[i]] do
  1072. X      if groupMark <> grpMark then
  1073. X        begin
  1074. X          if atLevel <> tryLevel then
  1075. X            begin
  1076. X              playMark := playMark + 1;
  1077. X              with playStack[playMark] do
  1078. X                begin
  1079. X                  kind := chLib;
  1080. X                  gID := nlcGroup.v[i];
  1081. X                  oldLevel := atLevel;
  1082. X                  oldLC := libC;
  1083. X                end;
  1084. X            end;
  1085. X          groupMark := grpMark;
  1086. X          atLevel := tryLevel;
  1087. X          spanGroup(lx, ly, pPList);
  1088. X          libC := pPList.indx;
  1089. X        end;
  1090. Xend { plei };
  1091. X
  1092. Xprocedure saveState;
  1093. Xbegin { saveState };
  1094. X  playMark := 0;
  1095. X  tryLevel := 0;
  1096. X  newGID := maxGroupID;
  1097. Xend { saveState };
  1098. X
  1099. X{
  1100. X  undoes a move sequence back to uMark
  1101. X}
  1102. Xprocedure undoTo(uMark: integer);
  1103. Xvar
  1104. X  i: integer;
  1105. Xbegin { undoTo }
  1106. X  for i := playMark downto uMark + 1 do
  1107. X    with playStack[i] do
  1108. X      if kind = rem then
  1109. X        begin
  1110. X          bord[xl, yl] := who;
  1111. X          groupIDs[xl, yl] := gID;
  1112. X          if showTrees then
  1113. X            sstone(who, xl, yl, sNumber);
  1114. X        end
  1115. X      else if kind = add then
  1116. X        begin
  1117. X          bord[xl, yl] := 0;
  1118. X          groupIDs[xl, yl] := 0;
  1119. X          tryLevel := tryLevel - 1;
  1120. X          newGID := nextGID;
  1121. X          if showTrees then
  1122. X            rstone(xl, yl);
  1123. X        end
  1124. X      else if kind = reMap then
  1125. X        gMap[gID] := oldGID
  1126. X      else { change libs of group - gID is pre-mapped }
  1127. X        with gList[gID] do
  1128. X          begin
  1129. X            libC := oldLC;
  1130. X            atLevel := oldLevel;
  1131. X          end;
  1132. X  playMark := uMark;
  1133. Xend { undoTo };
  1134. X
  1135. X{
  1136. X  restores the state of the world after trying a move sequence
  1137. X}
  1138. Xprocedure restoreState;
  1139. Xvar
  1140. X  i: integer;
  1141. Xbegin { restoreState }
  1142. X  if playMark > 0 then
  1143. X    begin
  1144. X      undoTo(0);
  1145. X      playMark := 0;
  1146. X      tryLevel := 0;
  1147. X    end;
  1148. Xend { restoreState };
  1149. X
  1150. Xexception bpt;
  1151. X
  1152. X{
  1153. X  returns true if the group (at x, y) is killable.
  1154. X  if so, returns the point to play at in killx, killy.
  1155. X}
  1156. Xfunction killable(gx, gy: integer; var killx, killy: integer): boolean;
  1157. Xconst
  1158. X  tryLimit = 300;
  1159. X
  1160. Xvar
  1161. X  me, him, depth, i, j, tryCount, tl, topMark, tkMark, mark2: integer;
  1162. X  sChar: char;
  1163. X  lList, dList: sPointList;
  1164. X  tp: point;
  1165. X  libList: array[1..maxSPoint] of integer;
  1166. X  esc: boolean;
  1167. X
  1168. X  function mtNbrs(x, y: integer): integer;
  1169. X  var
  1170. X    n: integer;
  1171. X  begin { mtNbrs }
  1172. X    n := 0;
  1173. X    if (x > 0) and (bord[x - 1, y] = 0) then
  1174. X      n := n + 1;
  1175. X    if (x < maxPoint) and (bord[x + 1, y] = 0) then
  1176. X      n := n + 1;
  1177. X    if (y > 0) and (bord[x, y - 1] = 0) then
  1178. X      n := n + 1;
  1179. X    if (y < maxPoint) and (bord[x, y + 1] = 0) then
  1180. X      n := n + 1;
  1181. X    mtNbrs := n;
  1182. X  end { mtNbrs };
  1183. X
  1184. X  function tKillTree(tx, ty: integer): boolean;
  1185. X  var
  1186. X    tkMark: integer;
  1187. X    escape: boolean;
  1188. X
  1189. X  function killTree(tx, ty: integer; var escape: boolean): boolean;
  1190. X    label
  1191. X      1, 2;
  1192. X    var
  1193. X      curMark, mark2, mark3, i, j, k, tl, dStart: integer;
  1194. X      lList1, lList2: sPointList;
  1195. X      libList: array[1..maxSPoint] of integer;
  1196. X      tp: point;
  1197. X      esc: boolean;
  1198. X    begin { killTree }
  1199. X      escape := false;
  1200. X      tryCount := tryCount + 1;
  1201. X      if tryCount > tryLimit then
  1202. X        begin
  1203. X          killable := false;
  1204. X          undoTo(tkMark);
  1205. X          for i := 1 to depth - 1 do
  1206. X            begin
  1207. X              sClearChar(sChar, rXor);
  1208. X            end;
  1209. X          depth := 1;
  1210. X          exit(tKilltree);
  1211. X        end;
  1212. X      write(sChar);
  1213. X      depth := depth + 1;
  1214. X      curMark := playMark;
  1215. X      plei(tx, ty, me); { try my move }
  1216. X      pause;
  1217. X      if gList[gMap[groupIDs[tx, ty]]].libC = 0 then { I'm dead }
  1218. X        killTree := false
  1219. X      else if killFlag then { I killed something of his }
  1220. X        killTree := true
  1221. X      else if gList[gMap[groupIDs[gx, gy]]].libC > treeLibLim then { safe }
  1222. X        killTree := false
  1223. X      else
  1224. X        begin
  1225. X          sSpanGroup(gx, gy, lList1); { find his liberties }
  1226. X          if gList[gMap[groupIDs[tx, ty]]].libC = 1 then { he can kill me }
  1227. X            begin
  1228. X              if lList1.indx < maxSPoint then { add that option to his list }
  1229. X                begin
  1230. X                  lList1.indx := lList1.indx + 1;
  1231. X                  spanGroup(tx, ty, pList2); { find my liberty }
  1232. X                  with lList1.p[lList1.indx] do
  1233. X                    begin
  1234. X                      px := pList2.p[1].px;
  1235. X                      py := pList2.p[1].py;
  1236. X                    end;
  1237. X                end
  1238. X              else
  1239. X                begin
  1240. X                  killTree := false; { forget it }
  1241. X                  goto 1;
  1242. X                end;
  1243. X            end;
  1244. X          for i := 1 to maxSPoint do    { init liblist so diags can be marked }
  1245. X            libList[i] := -1;
  1246. X          if (utilPlayLevel > 4) and
  1247. X             (lList1.indx > 1) and
  1248. X             (gList[gMap[groupIDs[gx, gy]]].libC > 1) then { try diags }
  1249. X            begin
  1250. X              listDiags(gx, gy, dList);
  1251. X              j := 0;
  1252. X              i := lList1.indx;
  1253. X              while (j < dList.indx) and
  1254. X                    (i < maxSPoint) do
  1255. X                begin
  1256. X                  j := j + 1;
  1257. X                  i := i + 1;
  1258. X                  libList[i] := 0;     { mark this as a diag }
  1259. X                  with dList.p[j] do
  1260. X                    begin
  1261. X                      lList1.p[i].px := px;
  1262. X                      lList1.p[i].py := py;
  1263. X                    end;
  1264. X                end;
  1265. X              lList1.indx := i;
  1266. X            end;
  1267. X          if lList1.indx > 1 then { sort by decreasing lib count }
  1268. X            begin
  1269. X              for i := 1 to lList1.indx do
  1270. X                if libList[i] <> 0 then       { diags are tried last }
  1271. X                  with lList1.p[i] do
  1272. X                    begin
  1273. X                      mark2 := playMark;
  1274. X                      plei(px, py, him);
  1275. X                      libList[i] := gList[gMap[groupIDs[gx, gy]]].libC;
  1276. X                      if (libList[i] > treeLibLim) or
  1277. X                         ((libList[i] > (depthLimit - depth)) and
  1278. X                          (libList[i] > 2)) then
  1279. X                        begin
  1280. X                          escape := true;
  1281. X                          killTree := false;
  1282. X                          goto 1; { he can live }
  1283. X                        end;
  1284. X                      undoTo(mark2);
  1285. X                    end;
  1286. X              for i := 1 to lList1.indx - 1 do
  1287. X                for j := i + 1 to lList1.indx do
  1288. X                  if libList[i] < libList[j] then
  1289. X                    begin
  1290. X                      tl := libList[i];
  1291. X                      libList[i] := libList[j];
  1292. X                      libList[j] := tl;
  1293. X                      tp := lList1.p[i];
  1294. X                      lList1.p[i] := lList1.p[j];
  1295. X                      lList1.p[j] := tp;
  1296. X                    end;
  1297. X            end;
  1298. X          for i := 1 to lList1.indx + 1 do { try his responses }
  1299. X            begin
  1300. X              mark2 := playMark;
  1301. X              if i <= lList1.indx then { try his move }
  1302. X                with lList1.p[i] do
  1303. X                  begin
  1304. X                    plei(px, py, him); { play his response }
  1305. X                    pause;
  1306. X                    if gList[gMap[groupIDs[px, py]]].libC < 2 then
  1307. X                      goto 2; { a bogus move }
  1308. X                  end
  1309. X              else if gList[gMap[groupIDs[gx, gy]]].libC <= 1 then
  1310. X                begin
  1311. X                  killTree := true; { can't tenuki if in atari }
  1312. X                  goto 1;
  1313. X                end;
  1314. X              if gList[gMap[groupIDs[gx, gy]]].libC > treeLibLim then
  1315. X                begin
  1316. X                  escape := true;
  1317. X                  killTree := false;
  1318. X                  goto 1;
  1319. X                end;
  1320. X              if gList[gMap[groupIDs[gx, gy]]].libC > 1 then
  1321. X                begin  { look at my responses }
  1322. X                  sSpanGroup(gx, gy, lList2); { list his liberties }
  1323. X                  dStart := lList2.indx + 1;
  1324. X                  if adjInAtari then { he wins }
  1325. X                     begin
  1326. X                       killTree := false;
  1327. X                       goto 1;
  1328. X                     end;
  1329. X                  if (lList2.Indx > 2) and adj2Libs then { he wins }
  1330. X                     begin
  1331. X                       killTree := false;
  1332. X                       goto 1;
  1333. X                     end;
  1334. X                  for k := 1 to maxSPoint do
  1335. X                    libList[k] := -1;
  1336. X                  if utilPlayLevel > 4 then { account for diagonal moves }
  1337. X                    begin
  1338. X                      listDiags(gx, gy, dList);
  1339. X                      j := 0;
  1340. X                      k := lList2.indx;
  1341. X                      while (j < dList.indx) and
  1342. X                            (k < maxSPoint) do
  1343. X                        begin
  1344. X                          j := j + 1;
  1345. X                          k := k + 1;
  1346. X                          libList[k] := 100;
  1347. X                          with dList.p[j] do
  1348. X                            begin
  1349. X                              lList2.p[k].px := px;
  1350. X                              lList2.p[k].py := py;
  1351. X                            end;
  1352. X                        end;
  1353. X                      lList2.indx := k;
  1354. X                    end;
  1355. X                  if lList2.indx > 1 then { sort by increasing lib count }
  1356. X                    begin
  1357. X                      for k := 1 to lList2.indx do
  1358. X                        if libList[k] <> 100 then     { diags go last }
  1359. X                          with lList2.p[k] do
  1360. X                            begin
  1361. X                              mark3 := playMark;
  1362. X                              plei(px, py, me);
  1363. X                              libList[k] := gList[gMap[groupIDs[gx, gy]]].libC;
  1364. X                              undoTo(mark3);
  1365. X                            end;
  1366. X                      for k := 1 to lList2.indx - 1 do
  1367. X                        for j := k + 1 to lList2.indx do
  1368. X                          if libList[k] > libList[j] then
  1369. X                            begin
  1370. X                              tl := libList[k];
  1371. X                              libList[k] := libList[j];
  1372. X                              libList[j] := tl;
  1373. X                              tp := lList2.p[k];
  1374. X                              lList2.p[k] := lList2.p[j];
  1375. X                              lList2.p[j] := tp;
  1376. X                            end
  1377. X                          else if (libList[k] = libList[j]) and
  1378. X                                  (libList[k] = 1) then
  1379. X                            if mtNbrs(lList2.p[k].px, lList2.p[k].py) <
  1380. X                               mtNbrs(lList2.p[j].px, lList2.p[j].py) then
  1381. X                              begin
  1382. X                                tl := libList[k];
  1383. X                                libList[k] := libList[j];
  1384. X                                libList[j] := tl;
  1385. X                                tp := lList2.p[k];
  1386. X                                lList2.p[k] := lList2.p[j];
  1387. X                                lList2.p[j] := tp;
  1388. X                              end;
  1389. X                    end;
  1390. X                  for j := 1 to lList2.indx do
  1391. X                    begin
  1392. X                      if killTree(lList2.p[j].px, lList2.p[j].py, esc) then
  1393. X                        goto 2; { this kills him }
  1394. X                      if esc and (j >= dStart) then
  1395. X                        begin
  1396. X                          killTree := false;
  1397. X                          goto 1; { don't bother with more diags if escapes }
  1398. X                        end;
  1399. X                    end;
  1400. X                  killTree := false;  { none of my responses kills him }
  1401. X                  goto 1;
  1402. X                end;
  1403. X    2:
  1404. X             undoTo(mark2);
  1405. X           end;
  1406. X          killTree := true; { none of his responses saves him }
  1407. X        end;
  1408. X    1:
  1409. X      undoTo(curMark);
  1410. X      sClearChar(sChar, rXor);
  1411. X      depth := depth - 1;
  1412. X    end { killTree };
  1413. X
  1414. X  begin { tKillTree }
  1415. X    tryCount := 0;
  1416. X    tkMark := playMark;
  1417. X    tKillTree := killTree(tx, ty, escape);
  1418. X  end { tKillTree };
  1419. X
  1420. Xbegin { killable }
  1421. X  dbStop := true;
  1422. X  him := bord[gx, gy]; { find out who I am }
  1423. X  me := -him;
  1424. X  if me = 1 then
  1425. X    sChar := '>'
  1426. X  else
  1427. X    sChar := '|';
  1428. X  write(sChar);
  1429. X  depth := 1;
  1430. X  topMark := playMark;
  1431. X  sSpanGroup(gx, gy, lList); { find his liberties }
  1432. X  if lList.indx = 1 then
  1433. X    begin
  1434. X      killable := true;
  1435. X      killx := lList.p[1].px;
  1436. X      killy := lList.p[1].py;
  1437. X    end
  1438. X  else if lList.indx > treeLibLim then
  1439. X    killable := false
  1440. X  else if adjInAtari then
  1441. X    killable := false
  1442. X  else if (lList.indx > 2) and adj2Libs then
  1443. X    killable := false
  1444. X  else
  1445. X    begin
  1446. X      for i := 1 to maxSPoint do
  1447. X        libList[i] := -1;
  1448. X      if utilPlayLevel > 4 then { account for diagonal moves }
  1449. X        begin
  1450. X          listDiags(gx, gy, dList);
  1451. X          j := 0;
  1452. X          i := lList.indx;
  1453. X          while (j < dList.indx) and
  1454. X                (i < maxSPoint) do
  1455. X            begin
  1456. X              j := j + 1;
  1457. X              i := i + 1;
  1458. X              libList[i] := 100;
  1459. X              with dList.p[j] do
  1460. X                begin
  1461. X                  lList.p[i].px := px;
  1462. X                  lList.p[i].py := py;
  1463. X                end;
  1464. X            end;
  1465. X          lList.indx := i;
  1466. X        end;
  1467. X      if lList.indx > 1 then { sort by increasing lib count }
  1468. X        begin
  1469. X          for i := 1 to lList.indx do
  1470. X            if libList[i] <> 100 then  { diags go last }
  1471. X              with lList.p[i] do
  1472. X                begin
  1473. X                  mark2 := playMark;
  1474. X                  plei(px, py, me);
  1475. X                  libList[i] := gList[gMap[groupIDs[gx, gy]]].libC;
  1476. X                  undoTo(mark2);
  1477. X                end;
  1478. X          for i := 1 to lList.indx - 1 do
  1479. X            for j := i + 1 to lList.indx do
  1480. X              if libList[i] > libList[j] then
  1481. X                begin
  1482. X                  tl := libList[i];
  1483. X                  libList[i] := libList[j];
  1484. X                  libList[j] := tl;
  1485. X                  tp := lList.p[i];
  1486. X                  lList.p[i] := lList.p[j];
  1487. X                  lList.p[j] := tp;
  1488. X                end
  1489. X              else if (libList[i] = libList[j]) and
  1490. X                      (libList[i] = 1) then
  1491. X                if mtNbrs(lList.p[i].px, lList.p[i].py) <
  1492. X                   mtNbrs(lList.p[j].px, lList.p[j].py) then
  1493. X                  begin
  1494. X                    tl := libList[i];
  1495. X                    libList[i] := libList[j];
  1496. X                    libList[j] := tl;
  1497. X                    tp := lList.p[i];
  1498. X                    lList.p[i] := lList.p[j];
  1499. X                    lList.p[j] := tp;
  1500. X                  end;
  1501. X        end;
  1502. X      for i := 1 to lList.indx do
  1503. X        begin
  1504. X          if legal[lList.p[i].px, lList.p[i].py] then
  1505. X            begin
  1506. X              killx := lList.p[i].px;
  1507. X              killy := lList.p[i].py;
  1508. X              if tKillTree(killx, killy) then
  1509. X                begin
  1510. X                  killable := true;
  1511. X                  sClearChar(sChar, rXor);
  1512. X                  exit(killable);
  1513. X                end;
  1514. X            end;
  1515. X        end;
  1516. X      killable := false;
  1517. X    end;
  1518. X  sClearChar(sChar, rXor);
  1519. Xend { killable };
  1520. X
  1521. X{
  1522. X  returns true if the group (at gx, gy) is saveable.
  1523. X  if so, returns the point to play at in savex, savey
  1524. X}
  1525. Xfunction saveable(gx, gy: integer; var savex, savey: integer): boolean;
  1526. Xlabel
  1527. X  1;
  1528. Xvar
  1529. X  me, him, gx1, gx2, i, j, smark, mark2, tl: integer;
  1530. X  sChar: char;
  1531. X  dList: sPointList;
  1532. X  tp: point;
  1533. X  libList: array[1..maxSPoint] of integer;
  1534. Xbegin { saveable }
  1535. X  dbStop := true;
  1536. X  me := bord[gx, gy];
  1537. X  him := -me;
  1538. X  if me = 1 then
  1539. X    sChar := '|'
  1540. X  else
  1541. X    sChar := '>';
  1542. X  write(sChar);
  1543. X  spanGroup(gx, gy, pList3); { find my liberties }
  1544. X  if adjInAtari then { one of my options is to kill }
  1545. X    begin
  1546. X      listAdjacents(gx, gy, aList);
  1547. X      for i := 1 to aList.indx do
  1548. X        if gList[aList.v[i]].libC = 1 then
  1549. X          with gList[aList.v[i]] do
  1550. X            begin
  1551. X              spanGroup(lx, ly, pList1); { find it's liberty }
  1552. X              pList3.indx := pList3.indx + 1;
  1553. X              pList3.p[pList3.indx].px := pList1.p[1].px;
  1554. X              pList3.p[pList3.indx].py := pList1.p[1].py;
  1555. X            end;
  1556. X    end;
  1557. X  for i := 1 to maxSPoint do
  1558. X    libList[i] := -1;
  1559. X  if (utilPlayLevel > 4) and
  1560. X     (gList[gMap[groupIDs[gx, gy]]].libC > 1) then { account for diags }
  1561. X    begin
  1562. X      listDiags(gx, gy, dList);
  1563. X      j := 0;
  1564. X      i := pList3.indx;
  1565. X      while (j < dList.indx) and
  1566. X            (i < maxSPoint) do
  1567. X        begin
  1568. X          j := j + 1;
  1569. X          i := i + 1;
  1570. X          libList[i] := 100;
  1571. X          with dList.p[j] do
  1572. X            begin
  1573. X              pList3.p[i].px := px;
  1574. X              pList3.p[i].py := py;
  1575. X            end;
  1576. X        end;
  1577. X      pList3.indx := i;
  1578. X    end;
  1579. X  if pList3.indx > 1 then { sort by decreasing lib count }
  1580. X    begin
  1581. X      for i := 1 to pList3.indx do
  1582. X        if libList[i] <> 100 then
  1583. X          with pList3.p[i] do
  1584. X            begin
  1585. X              mark2 := playMark;
  1586. X              plei(px, py, me);
  1587. X              libList[i] := gList[gMap[groupIDs[gx, gy]]].libC;
  1588. X              if libList[i] > treeLibLim then { i'm safe }
  1589. X                begin
  1590. X                  savex := px;
  1591. X                  savey := py;
  1592. X                  saveable := true;
  1593. X                  goto 1;
  1594. X                end;
  1595. X              undoTo(mark2);
  1596. X            end;
  1597. X      for i := 1 to pList3.indx - 1 do
  1598. X        for j := i + 1 to pList3.indx do
  1599. X          if libList[i] < libList[j] then
  1600. X            begin
  1601. X              tl := libList[i];
  1602. X              libList[i] := libList[j];
  1603. X              libList[j] := tl;
  1604. X              tp := pList3.p[i];
  1605. X              pList3.p[i] := pList3.p[j];
  1606. X              pList3.p[j] := tp;
  1607. X            end;
  1608. X    end;
  1609. X  for i := 1 to pList3.indx do
  1610. X    begin
  1611. X      savex := pList3.p[i].px;
  1612. X      savey := pList3.p[i].py;
  1613. X      if legal[savex, savey] then
  1614. X        begin
  1615. X          smark := playMark;
  1616. X          plei(savex, savey, me);
  1617. X          pause;
  1618. X          if gList[gMap[groupIDs[savex, savey]]].libC > 1 then
  1619. X            if gList[gMap[groupIDs[gx, gy]]].libC > treeLibLim then
  1620. X              begin
  1621. X                saveable := true;
  1622. X                restoreState;
  1623. X                sClearChar(sChar, rXor);
  1624. X                exit(saveable);
  1625. X              end
  1626. X            else if gList[gMap[groupIDs[gx, gy]]].libC > 1 then
  1627. X              if not killable(gx, gy, gx1, gx2) then
  1628. X                begin
  1629. X                  saveable := true;
  1630. X                  restoreState;
  1631. X                  sClearChar(sChar, rXor);
  1632. X                  exit(saveable);
  1633. X                end;
  1634. X          undoTo(smark);
  1635. X        end;
  1636. X    end;
  1637. X  saveable := false;
  1638. X1:
  1639. X  restoreState;
  1640. X  sClearChar(sChar, rXor);
  1641. Xend { saveable };
  1642. X
  1643. X{
  1644. X  marks unsavable groups as dead
  1645. X}
  1646. Xprocedure markDead;
  1647. Xvar
  1648. X  i, j, gx, gy: integer;
  1649. Xbegin { markDead }
  1650. X  for i := 1 to maxGroupID do
  1651. X    with gList[i] do
  1652. X      if killable(lx, ly, gx, gy) then
  1653. X        isDead := not saveable(lx, ly, gx, gy)
  1654. X      else
  1655. X        isDead := false;
  1656. X  for i := 0 to maxPoint do
  1657. X    for j := 0 to maxPoint do
  1658. X      if bord[i, j] = 0 then
  1659. X        ndbord[i, j] := 0
  1660. X      else if gList[groupIDs[i, j]].isDead then
  1661. X        ndbord[i, j] := 0
  1662. X      else
  1663. X        ndbord[i, j] := bord[i, j];
  1664. Xend { markDead };
  1665. X
  1666. X{
  1667. X  marks groups with two eyes as live
  1668. X}
  1669. Xprocedure markLive;
  1670. Xvar
  1671. X  i, j, size, sMark: integer;
  1672. X  saw1, sawm1: boolean;
  1673. X
  1674. X  procedure span(x, y: integer);
  1675. X  begin { span }
  1676. X    if ndbord[x, y] = 1 then
  1677. X      saw1 := true
  1678. X    else if ndbord[x, y] = -1 then
  1679. X      sawm1 := true
  1680. X    else if sGroups[x, y] = 0 then
  1681. X      begin
  1682. X        sGroups[x, y] := sMark;
  1683. X        size := size + 1;
  1684. X        if x > 0 then
  1685. X          span(x - 1, y);
  1686. X        if x < maxPoint then
  1687. X          span(x + 1, y);
  1688. X        if y > 0 then
  1689. X          span(x, y - 1);
  1690. X        if y < maxPoint then
  1691. X          span(x, y + 1);
  1692. X      end;
  1693. X  end { span };
  1694. X
  1695. X  function checkLive(x, y: integer): boolean;
  1696. X  var
  1697. X    numEyes, who: integer;
  1698. X
  1699. X    procedure span(x, y: integer);
  1700. X    begin { span }
  1701. X      markBoard[x, y] := marker;
  1702. X      if ndbord[x, y] = 0 then
  1703. X        with sList[sGroups[x, y]] do
  1704. X          begin
  1705. X            if (sm <> marker) and
  1706. X               (w = who) then
  1707. X              begin
  1708. X                sm := marker;
  1709. X                if s > 6 then
  1710. X                  exit(checkLive);
  1711. X                numEyes := numEyes + 1;
  1712. X                if numEyes > 1 then
  1713. X                  exit(checkLive);
  1714. X              end;  
  1715. X          end
  1716. X      else if bord[x, y] = who then
  1717. X        begin
  1718. X          if (x > 0) and
  1719. X             (markBoard[x - 1, y] <> marker) then
  1720. X            span(x - 1, y);
  1721. X          if (x < maxPoint) and
  1722. X             (markBoard[x + 1, y] <> marker) then
  1723. X            span(x + 1, y);
  1724. X          if (y > 0) and
  1725. X             (markBoard[x, y - 1] <> marker) then
  1726. X            span(x, y - 1);
  1727. X          if (y < maxPoint) and
  1728. X             (markBoard[x, y + 1] <> marker) then
  1729. X            span(x, y + 1);
  1730. X        end;
  1731. X    end { span };
  1732. X
  1733. X  begin { checkLive }
  1734. X    checkLive := true;
  1735. X    numEyes := 0;
  1736. X    who := bord[x, y];
  1737. X    marker := marker + 1;
  1738. X    span(x, y);
  1739. X    checkLive := false;
  1740. X  end { checkLive };
  1741. X
  1742. Xbegin { markLive }
  1743. X  sMark := 0;
  1744. X  initArray(sGroups);
  1745. X  for i := 0 to maxPoint do
  1746. X    for j := 0 to maxPoint do
  1747. X      if (sGroups[i, j] = 0) and
  1748. X         (ndbord[i, j] = 0) then
  1749. X        begin
  1750. X          size := 0;
  1751. X          sMark := sMark + 1;
  1752. X          sawm1 := false;
  1753. X          saw1 := false;
  1754. X          span(i, j);
  1755. X          sList[sMark].s := size;
  1756. X          sList[sMark].sm := 0;
  1757. X          if sawm1 then
  1758. X            if saw1 then
  1759. X              sList[sMark].w := 0
  1760. X            else
  1761. X              sList[sMark].w := -1
  1762. X          else if saw1 then
  1763. X            sList[sMark].w := 1
  1764. X          else
  1765. X            sList[sMark].w := 0;
  1766. X        end;
  1767. X  for i := 1 to maxGroupID do
  1768. X    with gList[i] do
  1769. X      if not isDead then
  1770. X        isLive := checkLive(lx, ly);
  1771. Xend { markLive };
  1772. X
  1773. X{
  1774. X  generates the connection map and the protected point map.
  1775. X}
  1776. Xprocedure genConnects;
  1777. Xvar
  1778. X  x, y, numStones: integer;
  1779. Xbegin { genConnects }
  1780. X  for x := 0 to maxPoint do
  1781. X    for y := 0 to maxPoint do
  1782. X      begin
  1783. X        connectMap[x, y] := 0;
  1784. X        protPoints[x, y] := 0;
  1785. X      end;
  1786. X  for x := 0 to maxPoint do
  1787. X    for y := 0 to maxPoint do
  1788. X      if bord[x, y] = 1 then   { map connections to this stone }
  1789. X        begin
  1790. X          if x > 0 then        { direct connection }
  1791. X            connectMap[x - 1, y] := connectMap[x - 1, y] + 1;
  1792. X          if x < maxPoint then
  1793. X            connectMap[x + 1, y] := connectMap[x + 1, y] + 1;
  1794. X          if y > 0 then
  1795. X            connectMap[x, y - 1] := connectMap[x, y - 1] + 1;
  1796. X          if y < maxPoint then
  1797. X            connectMap[x, y + 1] := connectMap[x, y + 1] + 1;
  1798. X          if (x > 0) and (y > 0) and   { diagonal connection }
  1799. X             (bord[x - 1, y] = 0) and (bord[x, y - 1] = 0) then
  1800. X            connectMap[x - 1, y - 1] := connectMap[x - 1, y - 1] + 1;
  1801. X          if (x < maxPoint) and (y > 0) and
  1802. X             (bord[x + 1, y] = 0) and (bord[x, y - 1] = 0) then
  1803. X            connectMap[x + 1, y - 1] := connectMap[x + 1, y - 1] + 1; 
  1804. X          if (x < maxPoint) and (y < maxPoint) and
  1805. X             (bord[x + 1, y] = 0) and (bord[x, y + 1] = 0) then
  1806. X            connectMap[x + 1, y + 1] := connectMap[x + 1, y + 1] + 1; 
  1807. X          if (x > 0) and (y < maxPoint) and
  1808. X             (bord[x - 1, y] = 0) and (bord[x, y + 1] = 0) then
  1809. X            connectMap[x - 1, y + 1] := connectMap[x - 1, y + 1] + 1; 
  1810. X          if (x > 1) and (kleim[x - 1, y] > 3) then   { one point jump }
  1811. X            connectMap[x - 2, y] := connectMap[x - 2, y] + 1; 
  1812. X          if (x < (maxPoint - 1)) and (kleim[x + 1, y] > 3) then
  1813. X            connectMap[x + 2, y] := connectMap[x + 2, y] + 1; 
  1814. X          if (y > 1) and (kleim[x, y - 1] > 3) then
  1815. X            connectMap[x, y - 2] := connectMap[x, y - 2] + 1; 
  1816. X          if (y < (maxPoint - 1)) and (kleim[x, y + 1] > 3) then
  1817. X            connectMap[x, y + 2] := connectMap[x, y + 2] + 1;
  1818. X          if (x > 1) and (y > 0) and        { knight's move }
  1819. X             (kleim[x - 1, y] > 3) and (kleim[x - 1, y - 1] > 3) then
  1820. X            connectMap[x - 2, y - 1] := connectMap[x - 2, y - 1] + 1;
  1821. X          if (x > 0) and (y > 1) and
  1822. X             (kleim[x, y - 1] > 3) and (kleim[x - 1, y - 1] > 3) then
  1823. X            connectMap[x - 1, y - 2] := connectMap[x - 1, y - 2] + 1;
  1824. X          if (x < (maxPoint - 1)) and (y > 0) and
  1825. X             (kleim[x + 1, y] > 3) and (kleim[x + 1, y - 1] > 3) then
  1826. X            connectMap[x + 2, y - 1] := connectMap[x + 2, y - 1] + 1;
  1827. X          if (x < maxPoint) and (y > 1) and
  1828. X             (kleim[x, y - 1] > 3) and (kleim[x + 1, y - 1] > 3) then
  1829. X            connectMap[x + 1, y - 2] := connectMap[x + 1, y - 2] + 1;
  1830. X          if (x > 1) and (y < maxPoint) and
  1831. X             (kleim[x - 1, y] > 3) and (kleim[x - 1, y + 1] > 3) then
  1832. X            connectMap[x - 2, y + 1] := connectMap[x - 2, y + 1] + 1;
  1833. X          if (x > 0) and (y < (maxPoint - 1)) and
  1834. X             (kleim[x, y + 1] > 3) and (kleim[x - 1, y + 1] > 3) then
  1835. X            connectMap[x - 1, y + 2] := connectMap[x - 1, y + 2] + 1;
  1836. X          if (x < (maxPoint - 1)) and (y < maxPoint) and
  1837. X             (kleim[x + 1, y] > 3) and (kleim[x + 1, y + 1] > 3) then
  1838. X            connectMap[x + 2, y + 1] := connectMap[x + 2, y + 1] + 1;
  1839. X          if (x < maxPoint) and (y < (maxPoint - 1)) and
  1840. X             (kleim[x, y + 1] > 3) and (kleim[x + 1, y + 1] > 3) then
  1841. X            connectMap[x + 1, y + 2] := connectMap[x + 1, y + 2] + 1;
  1842. X        end
  1843. X      else if bord[x, y] = 0 then { see if protected point }
  1844. X        begin
  1845. X          numStones := 0;
  1846. X          if x = 0 then
  1847. X            numStones := numStones + 1;
  1848. X          if y = 0 then
  1849. X            numStones := numStones + 1;
  1850. X          if x = maxPoint then
  1851. X            numStones := numStones + 1;
  1852. X          if y = maxPoint then
  1853. X            numStones := numStones + 1;
  1854. X          if (x > 0) and (bord[x - 1, y] = 1) then
  1855. X            numStones := numStones + 1;
  1856. X          if (y > 0) and (bord[x, y - 1] = 1) then
  1857. X            numStones := numStones + 1;
  1858. X          if (x < maxPoint) and (bord[x + 1, y] = 1) then
  1859. X            numStones := numStones + 1;
  1860. X          if (y < maxPoint) and (bord[x, y + 1] = 1) then
  1861. X            numStones := numStones + 1;
  1862. X          if numStones = 4 then
  1863. X            protPoints[x, y] := 1
  1864. X          else if numStones = 3 then
  1865. X            begin
  1866. X              if (x > 0) and
  1867. X                 ((bord[x - 1, y] = 0) or
  1868. X                  ((bord[x - 1, y] = -1) and
  1869. X                   (gList[groupIDs[x - 1, y]].libC = 1))) then
  1870. X                 protPoints[x, y] := 1
  1871. X              else if (x < maxPoint) and
  1872. X                      ((bord[x + 1, y] = 0) or
  1873. X                       ((bord[x + 1, y] = -1) and
  1874. X                        (gList[groupIDs[x + 1, y]].libC = 1))) then
  1875. X                 protPoints[x, y] := 1
  1876. X              else if (y > 0) and
  1877. X                      ((bord[x, y - 1] = 0) or
  1878. X                       ((bord[x, y - 1] = -1) and
  1879. X                        (gList[groupIDs[x, y - 1]].libC = 1))) then
  1880. X                 protPoints[x, y] := 1
  1881. X              else if (y < maxPoint) and
  1882. X                      ((bord[x, y + 1] = 0) or
  1883. X                       ((bord[x, y + 1] = -1) and
  1884. X                        (gList[groupIDs[x, y + 1]].libC = 1))) then
  1885. X                 protPoints[x, y] := 1
  1886. X            end;
  1887. X        end; 
  1888. X  for x := 0 to maxPoint do
  1889. X    for y := 0 to maxPoint do
  1890. X      if bord[x, y] <> 0 then
  1891. X        begin
  1892. X          connectMap[x, y] := 0;
  1893. X          protPoints[x, y] := 0;
  1894. X        end;
  1895. Xend { genConnects };
  1896. X
  1897. X{
  1898. X  generates the whole state of the game.
  1899. X}
  1900. Xprocedure genState;
  1901. Xvar
  1902. X  i, j: integer;
  1903. Xbegin { genState }
  1904. X  inGenState := true;
  1905. X  respreicen;
  1906. X  markDead;
  1907. X  markLive;
  1908. X  spread;
  1909. X  genConnects;
  1910. X  inGenState := false;
  1911. Xend { genState };
  1912. X
  1913. X{
  1914. X  generates a value for the [x, y] location that appears to get larger
  1915. X  for points that are saddle points in the influence graph (klein)
  1916. X}
  1917. Xfunction tencen(x, y: integer): integer;
  1918. Xvar
  1919. X  a, b, c, d, w, z: integer;
  1920. Xbegin { tencen }
  1921. X  if kleim[x, y] > -1 then  { if he does not influence this area, return 50 }
  1922. X    begin
  1923. X      tencen := 50;
  1924. X      exit(tencen);
  1925. X    end;
  1926. X  w := kleim[x, y]; { w <= -1 }
  1927. X  a := iNil;
  1928. X  if x > 0 then
  1929. X    if kleim[x - 1, y] > -1 then  { if neighbor is not influenced by him }
  1930. X      a := kleim[x - 1, y] - w;   { score is sum of his influence on central }
  1931. X  b := iNil;                      {  point and my influence on this neighbor }
  1932. X  if y > 0 then
  1933. X    if kleim[x, y - 1] > -1 then
  1934. X      b := kleim[x, y - 1] - w;
  1935. X  c := iNil;
  1936. X  if x < maxPoint then
  1937. X    if kleim[x + 1, y] > -1 then
  1938. X      c := kleim[x + 1, y] - w;
  1939. X  d := iNil;
  1940. X  if y < maxPoint then
  1941. X    if kleim[x, y + 1] > -1 then
  1942. X      d := kleim[x, y + 1] - w;
  1943. X  z := a;             { z := max(a, b, c, d) }
  1944. X  if z <> iNil then
  1945. X    begin
  1946. X      if (b <> iNil) and
  1947. X         (b > z) then
  1948. X        z := b;
  1949. X    end
  1950. X  else
  1951. X    z := b; 
  1952. X  if z <> iNil then
  1953. X    begin
  1954. X      if (c <> iNil) and
  1955. X         (c > z) then
  1956. X        z := c;
  1957. X    end
  1958. X  else
  1959. X    z := c; 
  1960. X  if z <> iNil then
  1961. X    begin
  1962. X      if (d <> iNil) and
  1963. X         (d > z) then
  1964. X        z := d;
  1965. X    end
  1966. X  else
  1967. X    z := d; 
  1968. X  if (z <> iNil) and
  1969. X     ((x = 0) or
  1970. X      (y = 0) or
  1971. X      (x = maxPoint) or
  1972. X      (y = maxPoint)) then
  1973. X    z := z * 2;     { double z if on the edge of the board ?? }
  1974. X  if z <> iNil then
  1975. X    tencen := z
  1976. X  else
  1977. X    tencen := 50;
  1978. Xend { tencen };
  1979. X
  1980. Xprocedure initGPUtils;
  1981. Xbegin { initGPUtils }
  1982. X  initArray(markBoard);
  1983. X  initState;
  1984. X  marker := 0;
  1985. X  playMark := 0;
  1986. X  with gList[0] do
  1987. X    begin
  1988. X      isLive := false;
  1989. X      isDead := false;
  1990. X      libC := 0;
  1991. X      size := 0;
  1992. X      numEyes := 0;
  1993. X      lx := -1;
  1994. X      ly := -1;
  1995. X    end;
  1996. X  gMap[0] := 0;
  1997. X  dbStop := false;
  1998. X  inGenState := false;
  1999. Xend. { initGPUtils }
  2000. X
  2001. END_OF_goPlayUtils.pas
  2002. if test 50784 -ne `wc -c <goPlayUtils.pas`; then
  2003.     echo shar: \"goPlayUtils.pas\" unpacked with wrong size!
  2004. fi
  2005. # end of overwriting check
  2006. fi
  2007. echo shar: End of archive 1 \(of 5\).
  2008. cp /dev/null ark1isdone
  2009. MISSING=""
  2010. for I in 1 2 3 4 5 ; do
  2011.     if test ! -f ark${I}isdone ; then
  2012.     MISSING="${MISSING} ${I}"
  2013.     fi
  2014. done
  2015. if test "${MISSING}" = "" ; then
  2016.     echo You have unpacked all 5 archives.
  2017.     rm -f ark[1-9]isdone
  2018. else
  2019.     echo You still need to unpack the following archives:
  2020.     echo "        " ${MISSING}
  2021. fi
  2022. ##  End of shell archive.
  2023. exit 0
  2024.